// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// Author: Markus Gutschke

#include <fcntl.h>
#include <stdlib.h>
#include <sys/time.h>
#include <time.h>
#include <unistd.h>

#include "base64.h"
#include <limits.h>
#include "misc.h"
#include "check.h"


const char *uniqueID(void) {
  char fd;
  check((fd = open("/dev/urandom", O_RDONLY)) > 0);
  char in[UNIQUE_ID_LEN/4*3];
  check(UNIQUE_ID_LEN == (sizeof(in)+2)/3*4);
  check(read(fd, in, sizeof(in)) == sizeof(in));
  close(fd);
  char *out;
  check(out = malloc(UNIQUE_ID_LEN+1));
  b64encode(out, in, sizeof(in));
  return out;
}

pid_t pid(void) {
  static pid_t p = 0;
  if (!p) {
    p = getpid();
    check(p > 0);
    srand(p ^ time(NULL));
  }
  return p;
}

const char *hostname(void) {
  static char h[HOST_NAME_MAX + 1] = { 0 };
  if (!*h) {
    check(!gethostname(h, sizeof(h) - 1) && *h);
    for (char *ptr = h; *ptr; ++ptr) {
      check((*ptr >= '0' && *ptr <= '9') ||
            (*ptr >= 'A' && *ptr <= 'Z') ||
            (*ptr >= 'a' && *ptr <= 'z') ||
            *ptr == '-');
    }
  }
  return h;
}

unsigned long millis(void) {
  struct timeval tv = { 0 };
  gettimeofday(&tv, NULL);
  return (unsigned long)tv.tv_sec*1000UL + (unsigned long)tv.tv_usec/1000UL;
}
